////////////////////////////////////////////////////////////////////////////
//
//  Crytek Engine Source File.
//  Copyright (C), Crytek Studios, 2002.
// -------------------------------------------------------------------------
//  File name:   toolsconfigpage.cpp
//  Version:     v1.00
//  Created:     27/11/2002 by Timur.
//  Compilers:   Visual Studio.NET
//  Description: 
// -------------------------------------------------------------------------
//  History:
//
////////////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "ToolsConfigPage.h"
#include "ToolBox.h"
#include "MainFrm.h"

namespace
{
	COLORREF COLOR_FOR_EDITOR_COMMAND			= RGB(0,255,0);
	COLORREF COLOR_FOR_CONSOLE_COMMAND		= RGB(0,0,255);
	COLORREF COLOR_FOR_TOGGLE_COMMAND			= RGB(128,0,255);
	COLORREF COLOR_FOR_INVALID_COMMAND		= RGB(255,0,0);

	UINT CONSOLE_CMD_DROP_LIST_HEIGHT			= 300;
};

CIconListDialog::CIconListDialog(CWnd *pParent /* = NULL */)
							: CDialog(CIconListDialog::IDD, pParent)
{
}

void CIconListDialog::DoDataExchange(CDataExchange *pDX)
{
	__super::DoDataExchange(pDX);

	DDX_Control(pDX, IDC_ICON_LIST, m_iconListCtrl);
}

BEGIN_MESSAGE_MAP(CIconListDialog, CDialog)
END_MESSAGE_MAP()

BOOL CIconListDialog::OnInitDialog()
{
	__super::OnInitDialog();

	CFileUtil::FileArray pngFiles;

	// Search for the png files in Editor/UI/Icons folder
	// and add them to the image list.
	const int iconSize = 32;	// Currently, accepts the image of this size only.
	CString iconsDir;
	if (gSettings.searchPaths[EDITOR_PATH_UI_ICONS].empty())
		return FALSE;
	iconsDir = gSettings.searchPaths[EDITOR_PATH_UI_ICONS][0];
	CFileUtil::ScanDirectory(iconsDir, "*.png", pngFiles);
	m_iconImages.Create(iconSize, iconSize, ILC_COLOR32, pngFiles.size(), 1);
	m_iconFiles.clear();
	m_iconFiles.reserve(pngFiles.size());
	for(size_t i=0; i<pngFiles.size(); ++i)
	{
		CBitmap bitmap;
		CString path = Path::Make(iconsDir, pngFiles[i].filename);
		HBITMAP hBmp = CXTPImageManagerIcon::LoadBitmapFromFile(path);
		if(hBmp == NULL)
			continue;
		bitmap.Attach(hBmp);
		BITMAP bm;
		bitmap.GetBitmap(&bm);
		if(bm.bmWidth == iconSize && bm.bmHeight == iconSize)
		{
			m_iconImages.Add(&bitmap, RGB(255,0,255));
			m_iconFiles.push_back(path);
		}
	}

	// Set the image list to the list control and add items to it.
	m_iconListCtrl.SetImageList(&m_iconImages, LVSIL_NORMAL);
	m_iconListCtrl.SetItemCount(m_iconImages.GetImageCount());
	for(int i=0; i<m_iconImages.GetImageCount(); ++i)
		m_iconListCtrl.InsertItem(i, NULL, i);
	m_iconListCtrl.SetExtendedStyle(LVS_EX_HIDELABELS);

	return TRUE;
}

bool CIconListDialog::GetSelectedIconPath(CString& path) const
{
	if(m_selectedIconPath.IsEmpty())
	{
		return false;
	}
	else
	{
		path = m_selectedIconPath;
		return true;
	}
}

void CIconListDialog::OnOK()
{
	POSITION pos = m_iconListCtrl.GetFirstSelectedItemPosition();
	if(pos)
	{
		int index = m_iconListCtrl.GetNextSelectedItem(pos);
		m_selectedIconPath = m_iconFiles[index];
	}
	else
	{
		m_selectedIconPath = "";
	}

	__super::OnOK();
}

// CToolsConfigPage dialog

IMPLEMENT_DYNAMIC(CToolsConfigPage, CXTResizePropertyPage)
CToolsConfigPage::CToolsConfigPage()
	: CXTResizePropertyPage(CToolsConfigPage::IDD),
		m_macroShortcutKey(((CMainFrame*)AfxGetMainWnd())->XTPShortcutManager())
{
		// Call CXTEditListBox::SetListEditStyle to set the type of edit list. You can
	// pass in LBS_XT_NOTOOLBAR if you don't want the toolbar displayed.
	m_macroList.SetListEditStyle(_T(" &Macros:"),	LBS_XT_DEFAULT);
	m_commandList.SetListEditStyle(_T(" &Commands:"),	LBS_XT_DEFAULT);
	m_commandList.SetNewItemDefaultText("nop");
	m_commandList.SetColorCallback(functor_ret(*this, &CToolsConfigPage::DetermineCommandItemColor));
}

CToolsConfigPage::~CToolsConfigPage()
{
}

void CToolsConfigPage::DoDataExchange(CDataExchange* pDX)
{
	CXTResizePropertyPage::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_COMBO1, m_consoleCmd);
	DDX_Control(pDX, IDC_TOGGLEVARONOFF, m_toggleVar);
	DDX_Control(pDX, IDC_APPLY_EDITOR_COMMAND, m_applyEditorCommand);
	DDX_Control(pDX, IDC_APPLY_CONSOLE_COMMAND, m_applyConsoleCommand);
	DDX_Control(pDX, IDC_ASSIGN_MACROSHORTCUT, m_assignShortcut);
	DDX_Control(pDX, IDC_CHOOSE_MACRO_ICON, m_selectIcon);
	DDX_Control(pDX, IDC_CLEAR_MACRO_ICON, m_clearIcon);
	DDX_Control(pDX, IDC_EDIT_LIST, m_macroList);
	DDX_Control(pDX, IDC_EDIT_MACRO, m_commandList);
	DDX_Control(pDX, IDC_EDITOR_COMMAND, m_editorCmd);
	DDX_Control(pDX, IDC_MACRO_SHORTCUT, m_macroShortcutKey);	
	DDX_Control(pDX, IDC_MACRO_ICON, m_macroIcon);	
}

BEGIN_MESSAGE_MAP(CToolsConfigPage, CXTResizePropertyPage)
	ON_BN_CLICKED(IDC_APPLY_EDITOR_COMMAND, OnApplyEditorCommand)
	ON_BN_CLICKED(IDC_APPLY_CONSOLE_COMMAND, OnApplyConsoleCommand)
	ON_BN_CLICKED(IDC_ASSIGN_MACROSHORTCUT, OnAssignMacroShortcut)
	ON_BN_CLICKED(IDC_CHOOSE_MACRO_ICON, OnSelectMacroIcon)
	ON_BN_CLICKED(IDC_CLEAR_MACRO_ICON, OnClearMacroIcon)

	ON_CBN_SELCHANGE(IDC_COMBO1, OnSelchangeConsoleCommand)
	
	ON_LBN_SELCHANGE(IDC_EDIT_LIST, OnSelchangeMacroList)
	ON_LBN_XT_NEWITEM(IDC_EDIT_LIST, OnNewMacroItem)
	ON_LBN_XT_LABELEDITEND(IDC_EDIT_LIST, OnMacroTitleEditEnd)
	ON_LBN_XT_MOVEITEMUP(IDC_EDIT_LIST, OnMoveMacroItemUp)
	ON_LBN_XT_MOVEITEMDOWN(IDC_EDIT_LIST, OnMoveMacroItemDown)
	ON_LBN_XT_DELETEITEM(IDC_EDIT_LIST, OnDeleteMacroItem)

	ON_LBN_SELCHANGE(IDC_EDIT_MACRO, OnSelchangeCommandList)
	ON_LBN_XT_NEWITEM(IDC_EDIT_MACRO, OnNewCommandItem)
	ON_LBN_XT_PRENEWITEM(IDC_EDIT_MACRO, OnPreNewCommandItem)
	ON_LBN_XT_MOVEITEMUP(IDC_EDIT_MACRO, OnMoveCommandItemUp)
	ON_LBN_XT_MOVEITEMDOWN(IDC_EDIT_MACRO, OnMoveCommandItemDown)
	ON_LBN_XT_DELETEITEM(IDC_EDIT_MACRO, OnDeleteCommandItem)
END_MESSAGE_MAP()


// CToolsConfigPage message handlers
BOOL CToolsConfigPage::OnInitDialog() 
{
	CXTResizePropertyPage::OnInitDialog();
	
	m_macroList.Initialize();
	m_commandList.Initialize();

	// Set control resizing.
	SetResize(IDC_EDIT_LIST, SZ_VERRESIZE(1));
	SetResize(IDC_EDIT_MACRO, SZ_RESIZE(1));
	SetResize(IDC_STATIC1, CXTResizeRect(0,1,1,1));
	SetResize(IDC_STATIC2, CXTResizeRect(0,1,1,1));
	SetResize(IDC_COMBO1, CXTResizeRect(0,1,1,1));
	SetResize(IDC_EDITOR_COMMAND, CXTResizeRect(0,1,1,1));
	SetResize(IDC_APPLY_EDITOR_COMMAND, SZ_REPOS(1));
	SetResize(IDC_APPLY_CONSOLE_COMMAND, SZ_REPOS(1));
	SetResize(IDC_TOGGLEVARONOFF, SZ_VERREPOS(1));
	SetResize(IDC_CHOOSE_MACRO_ICON, SZ_REPOS(1));
	SetResize(IDC_CLEAR_MACRO_ICON, SZ_REPOS(1));
	SetResize(IDC_MACRO_ICON, SZ_REPOS(1));
	SetResize(IDC_STATIC3, CXTResizeRect(0,1,1,1));
	SetResize(IDC_STATIC, SZ_REPOS(1));
	SetResize(IDC_ASSIGN_MACROSHORTCUT, SZ_REPOS(1));
	SetResize(IDC_MACRO_SHORTCUT, CXTResizeRect(0,1,1,1));

	CToolBoxManager *pTools = GetIEditor()->GetToolBoxManager();
	for (int i = 0; i < pTools->GetMacroCount(); ++i)
	{
		int id = m_macroList.AddString(pTools->GetMacro(i)->GetTitle());
		m_macroList.SetItemData(id, (DWORD_PTR)pTools->GetMacro(i));
	}

	{
		IConsole *console = GetIEditor()->GetSystem()->GetIConsole();
		std::vector<const char*> cmds;
		cmds.resize( console->GetNumVars() );
		size_t cmdCount = console->GetSortedVars( &cmds[0],cmds.size() );
		for (int i = 0; i < cmdCount; ++i)
		{
			m_consoleCmd.AddString(cmds[i]);
		}
		// Set tooltips for console commands.
		for (int i = 0; i < m_consoleCmd.GetCount(); ++i)
		{
			CString cmd;
			m_consoleCmd.GetLBText(i, cmd);
			ICVar *pCVar = console->GetCVar(cmd);
			if(pCVar && pCVar->GetHelp())
				m_consoleCmd.SetItemTip(i, pCVar->GetHelp());
		}
		m_consoleCmd.SetDroppedHeight(CONSOLE_CMD_DROP_LIST_HEIGHT);
	}

	{
		/// Fill editor commands.
		std::vector<CString> cmds;
		GetIEditor()->GetCommandManager()->GetSortedCmdList(cmds);
		for (int i = 0; i < cmds.size(); ++i)
		{
			m_editorCmd.AddString(cmds[i]);
		}
	}
	
	// To ensure the proper disabling of controls
	OnSelchangeMacroList();
	OnSelchangeCommandList();

	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}

//////////////////////////////////////////////////////////////////////////
void CToolsConfigPage::OnOK()
{
	GetIEditor()->GetToolBoxManager()->Save();

	CMainFrame*	pMainFrame=((CMainFrame*)AfxGetMainWnd());

	CXTPShortcutManager* pShortcutMgr = pMainFrame->XTPShortcutManager();
	if( pShortcutMgr )
		pShortcutMgr->SaveShortcuts( "Shortcuts" );
}

//////////////////////////////////////////////////////////////////////////
void CToolsConfigPage::OnCancel()
{
	CXTPShortcutManager* pShortcutMgr = ((CMainFrame*)AfxGetMainWnd())->XTPShortcutManager();
	if( pShortcutMgr )
		pShortcutMgr->LoadShortcuts( "Shortcuts" );

	// Revert to the original.
	GetIEditor()->GetToolBoxManager()->Load();
}

//////////////////////////////////////////////////////////////////////////
void CToolsConfigPage::OnSelchangeMacroList()
{
	int macroIndex = m_macroList.GetCurSel();
	m_commandList.ResetContent();

	if(macroIndex != LB_ERR)
	{
		/// Update the command list.
		CToolBoxMacro *pMacro = (CToolBoxMacro*)m_macroList.GetItemData(macroIndex);
		for(int i=0; i<pMacro->GetCommandCount(); ++i)
		{
			CToolBoxCommand *pCommand = pMacro->GetCommandAt(i);
			int id = m_commandList.AddString(pCommand->m_text);
			m_commandList.SetItemData(id, (DWORD_PTR)pCommand);
		}

		/// Update the shortcut.
		CXTPShortcutManager* pShortcutMgr = ((CMainFrame*)AfxGetMainWnd())->XTPShortcutManager();
		if( pShortcutMgr )
		{
			CXTPShortcutManagerAccel accel;
			m_macroShortcutKey.ResetKey();

			if( pShortcutMgr->GetShortcut(macroIndex+ID_TOOL1, &accel) )
			{	
				CString keyStr(pShortcutMgr->Format(&accel,NULL));
				m_macroShortcutKey.SetWindowText(keyStr);
				m_macroShortcutKey.SetAccel(&accel);
			}
			else
			{	
				m_macroShortcutKey.SetWindowText("");
			}
		}

		/// Update the icon.
		CString iconPath = pMacro->GetIconPath();
		if( iconPath.IsEmpty() )
		{
			DeleteObject(m_macroIcon.SetBitmap(NULL));
		}
		else
		{
			HBITMAP hBmp = CXTPImageManagerIcon::LoadBitmapFromFile(iconPath);
			DeleteObject(m_macroIcon.SetBitmap(hBmp));
		}

		m_macroShortcutKey.EnableWindow(TRUE);
		m_assignShortcut.EnableWindow(TRUE);
		m_selectIcon.EnableWindow(TRUE);
		m_clearIcon.EnableWindow(TRUE);
	}
	else
	{
		m_macroShortcutKey.EnableWindow(FALSE);
		m_assignShortcut.EnableWindow(FALSE);
		m_selectIcon.EnableWindow(FALSE);
		m_clearIcon.EnableWindow(FALSE);
	}

	m_commandList.SetCurSel(-1);
	OnSelchangeCommandList();
}

//////////////////////////////////////////////////////////////////////////
void CToolsConfigPage::OnNewMacroItem()
{
	int macroIndex = m_macroList.GetCurrentIndex();
	if (macroIndex != -1)
	{
		CString title;
		m_macroList.GetText(macroIndex, title);
		CToolBoxMacro *pMacro = GetIEditor()->GetToolBoxManager()->NewMacro(title);
		if(pMacro == NULL)
		{
			AfxMessageBox("There is a macro of that name, already!");
			m_macroList.DeleteString(macroIndex);
			return;
		}

		m_macroList.SetItemData(macroIndex, (DWORD_PTR)pMacro);
		m_macroList.SetCurSel(macroIndex);
		OnSelchangeMacroList();
	}
}

//////////////////////////////////////////////////////////////////////////
void CToolsConfigPage::OnSelchangeCommandList()
{
	int commandIndex = m_commandList.GetCurSel();

	if(commandIndex != LB_ERR)
	{
		m_applyEditorCommand.EnableWindow(TRUE);
		m_applyConsoleCommand.EnableWindow(TRUE);
		m_editorCmd.EnableWindow(TRUE);
		m_consoleCmd.EnableWindow(TRUE);
		m_toggleVar.EnableWindow(TRUE);
		CToolBoxCommand *pCommand = (CToolBoxCommand*)m_commandList.GetItemData(commandIndex);
		if(pCommand->m_type == CToolBoxCommand::eT_EDITOR_COMMAND)
		{
			m_editorCmd.SetWindowText(pCommand->m_text);
			m_consoleCmd.SetCurSel(-1);
			m_consoleCmd.SetWindowText("");
			OnSelchangeConsoleCommand();
			m_toggleVar.SetCheck(0);
			return;
		}
		else if(pCommand->m_type == CToolBoxCommand::eT_CONSOLE_COMMAND)
		{
			m_editorCmd.SetWindowText("");
			m_consoleCmd.SetCurSel(-1);
			m_consoleCmd.SetWindowText(pCommand->m_text);
			OnSelchangeConsoleCommand();
			m_toggleVar.SetCheck(pCommand->m_bVariableToggle?1:0);
			return;
		}
	}
	else
	{
		m_applyEditorCommand.EnableWindow(FALSE);
		m_applyConsoleCommand.EnableWindow(FALSE);
		m_editorCmd.EnableWindow(FALSE);
		m_consoleCmd.EnableWindow(FALSE);
		m_toggleVar.EnableWindow(FALSE);
	}

	m_editorCmd.SetWindowText("");
	m_consoleCmd.SetCurSel(-1);
	m_consoleCmd.SetWindowText("");
	OnSelchangeConsoleCommand();
	m_toggleVar.SetCheck(0);
}

//////////////////////////////////////////////////////////////////////////
void CToolsConfigPage::OnPreNewCommandItem()
{
	int macroIndex = m_macroList.GetCurSel();
	if(macroIndex == LB_ERR)
	{
		AfxMessageBox("You should first select a valid macro to which a command is added!");
		m_commandList.SendMessage(WM_KEYDOWN, VK_ESCAPE);
	}
}

//////////////////////////////////////////////////////////////////////////
void CToolsConfigPage::OnNewCommandItem()
{
	int macroIndex = m_macroList.GetCurSel();
	int commandIndex = m_commandList.GetCurrentIndex();
	assert(macroIndex != LB_ERR);
	if(commandIndex != -1)
	{
		m_commandList.DeleteString(commandIndex);
		m_commandList.InsertString(commandIndex, "nop");

		CToolBoxMacro *pMacro = (CToolBoxMacro*)m_macroList.GetItemData(macroIndex);
		pMacro->AddCommand(CToolBoxCommand::eT_INVALID_COMMAND, "nop");

		CToolBoxCommand *pCommandJustAdded = pMacro->GetCommandAt(pMacro->GetCommandCount()-1);
		m_commandList.SetItemData(commandIndex, (DWORD_PTR)pCommandJustAdded);
		m_commandList.SetCurSel(commandIndex);
	}
}

//////////////////////////////////////////////////////////////////////////
void CToolsConfigPage::OnApplyEditorCommand()
{
	int commandIndex = m_commandList.GetCurSel();
	if(commandIndex != LB_ERR)
	{
		CToolBoxCommand *pCommand = (CToolBoxCommand*)m_commandList.GetItemData(commandIndex);
		pCommand->m_type = CToolBoxCommand::eT_EDITOR_COMMAND;
		m_editorCmd.GetWindowText(pCommand->m_text);
		pCommand->m_bVariableToggle = false;
		m_commandList.DeleteString(commandIndex);
		m_commandList.InsertString(commandIndex, pCommand->m_text);
		m_commandList.SetItemData(commandIndex, (DWORD_PTR)pCommand);
	}
}

//////////////////////////////////////////////////////////////////////////
void CToolsConfigPage::OnApplyConsoleCommand()
{
	int commandIndex = m_commandList.GetCurSel();
	if(commandIndex != LB_ERR)
	{
		CToolBoxCommand *pCommand = (CToolBoxCommand*)m_commandList.GetItemData(commandIndex);
		pCommand->m_type = CToolBoxCommand::eT_CONSOLE_COMMAND;
		m_consoleCmd.GetWindowText(pCommand->m_text);
		pCommand->m_bVariableToggle = m_toggleVar.GetCheck()?true:false;
		m_commandList.DeleteString(commandIndex);
		m_commandList.InsertString(commandIndex, pCommand->m_text);
		m_commandList.SetItemData(commandIndex, (DWORD_PTR)pCommand);
	}
}

//////////////////////////////////////////////////////////////////////////
void CToolsConfigPage::OnAssignMacroShortcut()
{
	CXTPShortcutManager* pShortcutMgr = ((CMainFrame*)AfxGetMainWnd())->XTPShortcutManager();

	if( pShortcutMgr  == NULL )
		return;

	int macroIndex = m_macroList.GetCurSel();

	if( macroIndex == LB_ERR )
		return;

	CXTPShortcutManagerAccel editorAccel(*m_macroShortcutKey.GetAccel());
	CToolBoxMacro* pMacro = (CToolBoxMacro*)m_macroList.GetItemData(macroIndex);
	int id(macroIndex+ID_TOOL1); 
	editorAccel.cmd = id;

	CXTPShortcutManagerAccelTable* pAccelTable = pShortcutMgr->GetDefaultAccelerator();
	bool bReassign = false;

	for (int i = 0; i < pAccelTable->GetCount(); )
	{
		CXTPShortcutManagerAccel* accel = pAccelTable->GetAt(i);

		if( CXTPShortcutManager::CKeyHelper::EqualAccels(accel, &editorAccel) )
		{
			if( !bReassign && XTPResourceManager()->ShowMessageBox(XTP_IDS_CONFIRM_REASSIGN, MB_ICONWARNING | MB_YESNO) != IDYES )
			{	
				CToolBoxMacro* pMacro		= (CToolBoxMacro*)m_macroList.GetItemData(macroIndex);
				CXTPShortcutManagerAccel oldAccel;
				pShortcutMgr->GetShortcut( id, &oldAccel );
				CString oldShortcutName = pShortcutMgr->Format(&oldAccel,NULL);
				m_macroShortcutKey.ResetKey();
				m_macroShortcutKey.SetWindowText(oldShortcutName);
				m_macroShortcutKey.SetAccel(&oldAccel);
				return;
			}
			bReassign = true;
			pAccelTable->RemoveAt(i);			
			continue;
		}
		++i;
	}

	for (int i = 0; i < pAccelTable->GetCount(); i++)
	{
		CXTPShortcutManagerAccel* accel = pAccelTable->GetAt(i);
		if( accel->cmd == editorAccel.cmd )
		{
			pAccelTable->RemoveAt(i);
			i = 0;
			continue;
		}
	}	
	
	m_macroShortcutKey.ResetKey();
	if( CToolBoxManager::AddShortcut(editorAccel) )
	{
		CString keyText( pShortcutMgr->Format( &editorAccel, NULL ) );		
		m_macroShortcutKey.SetAccel(&editorAccel);
		m_macroShortcutKey.SetWindowText(keyText);
		pMacro->SetShortcutName(keyText);
	}
	else
	{	
		AfxMessageBox("This macro can't be assigned.");
	}
}


//////////////////////////////////////////////////////////////////////////
void CToolsConfigPage::OnMacroTitleEditEnd()
{
	int macroIndex = m_macroList.GetCurrentIndex();
	if(macroIndex != -1)
	{
		CToolBoxMacro* pMacro = (CToolBoxMacro*)m_macroList.GetItemData(macroIndex);
		CString newTitle;
		m_macroList.GetText(macroIndex, newTitle);
		CString oldTitle = pMacro->GetTitle();
		bool ok = GetIEditor()->GetToolBoxManager()->SetMacroTitle(macroIndex, newTitle);
		if(ok == false)
		{
			AfxMessageBox("There is a macro of that name, already!");
			// Revert to the original title.
			m_macroList.DeleteString(macroIndex);
			m_macroList.InsertString(macroIndex, pMacro->GetTitle());
			m_macroList.SetItemData(macroIndex, (DWORD_PTR)pMacro);
		}
	}
}

//////////////////////////////////////////////////////////////////////////
void CToolsConfigPage::OnMoveMacroItemUp()
{
	int macroIndex = m_macroList.GetCurrentIndex();
	if(macroIndex > 0)
		GetIEditor()->GetToolBoxManager()->SwapMacro(macroIndex, macroIndex-1);
	CToolBoxManager::UpdateShortcutsAndIcons();
}

//////////////////////////////////////////////////////////////////////////
void CToolsConfigPage::OnMoveMacroItemDown()
{
	int macroIndex = m_macroList.GetCurrentIndex();
	if(macroIndex < m_macroList.GetCount() - 1)
		GetIEditor()->GetToolBoxManager()->SwapMacro(macroIndex, macroIndex+1);
	CToolBoxManager::UpdateShortcutsAndIcons();
}

//////////////////////////////////////////////////////////////////////////
void CToolsConfigPage::OnMoveCommandItemUp()
{
	int macroIndex = m_macroList.GetCurSel();
	assert(macroIndex != LB_ERR);
	CToolBoxMacro *pMacro = (CToolBoxMacro*)m_macroList.GetItemData(macroIndex);
	int commandIndex = m_commandList.GetCurrentIndex();
	if(commandIndex > 0 && pMacro)
		pMacro->SwapCommand(commandIndex, commandIndex-1);
}

//////////////////////////////////////////////////////////////////////////
void CToolsConfigPage::OnMoveCommandItemDown()
{
	int macroIndex = m_macroList.GetCurSel();
	assert(macroIndex != LB_ERR);
	CToolBoxMacro *pMacro = (CToolBoxMacro*)m_macroList.GetItemData(macroIndex);
	int commandIndex = m_commandList.GetCurrentIndex();
	if(commandIndex < m_commandList.GetCount() - 1 && pMacro)
		pMacro->SwapCommand(commandIndex, commandIndex+1);
}

//////////////////////////////////////////////////////////////////////////
void CToolsConfigPage::OnDeleteMacroItem()
{
	int macroIndex = m_macroList.GetCurrentIndex();
	if(macroIndex != -1)
	{
		CToolBoxMacro* pMacro = GetIEditor()->GetToolBoxManager()->GetMacro(macroIndex);
		GetIEditor()->GetToolBoxManager()->RemoveMacro(macroIndex);
	}
	CToolBoxManager::UpdateShortcutsAndIcons();
	OnSelchangeMacroList();
}

//////////////////////////////////////////////////////////////////////////
void CToolsConfigPage::OnDeleteCommandItem()
{
	int macroIndex = m_macroList.GetCurSel();
	int commandIndex = m_commandList.GetCurrentIndex();
	if(macroIndex != LB_ERR && commandIndex != -1)
	{
		CToolBoxMacro *pMacro = (CToolBoxMacro*)m_macroList.GetItemData(macroIndex);
		pMacro->RemoveCommand(commandIndex);
	}
	OnSelchangeCommandList();
}

//////////////////////////////////////////////////////////////////////////
void CToolsConfigPage::OnSelchangeConsoleCommand()
{
	m_consoleCmd.SetComboTip("");
	int cmdIndex = m_consoleCmd.GetCurSel();
	CString consoleCmdText;
	if(cmdIndex == -1)
		m_consoleCmd.GetWindowText(consoleCmdText);
	else
		m_consoleCmd.GetLBText(cmdIndex, consoleCmdText);
	if(consoleCmdText.IsEmpty())
		return;
	// Get the just var/cmd part.
	int curPos = 0;
	consoleCmdText = consoleCmdText.Tokenize(" ", curPos);
	ICVar *pCVar = GetIEditor()->GetSystem()->GetIConsole()->GetCVar(consoleCmdText);
	if(pCVar && pCVar->GetHelp())
		m_consoleCmd.SetComboTip(pCVar->GetHelp());
}

//////////////////////////////////////////////////////////////////////////
COLORREF CToolsConfigPage::DetermineCommandItemColor(int index) const
{
	assert(0 <= index && index < m_commandList.GetCount());
	COLORREF color = COLOR_FOR_INVALID_COMMAND;
	CToolBoxCommand *pCommand = (CToolBoxCommand*)m_commandList.GetItemData(index);
	if(pCommand)
	{
		if(pCommand->m_type == CToolBoxCommand::eT_EDITOR_COMMAND)
			color = COLOR_FOR_EDITOR_COMMAND;
		else if(pCommand->m_type == CToolBoxCommand::eT_CONSOLE_COMMAND)
		{
			if(pCommand->m_bVariableToggle)
				color = COLOR_FOR_TOGGLE_COMMAND;
			else
				color = COLOR_FOR_CONSOLE_COMMAND;
		}
	}

	return color;
}

//////////////////////////////////////////////////////////////////////////
void CToolsConfigPage::OnSelectMacroIcon()
{
	int macroIndex = m_macroList.GetCurSel();
	if( macroIndex == LB_ERR )
		return;

	CToolBoxMacro* pMacro = (CToolBoxMacro*)m_macroList.GetItemData(macroIndex);

	CIconListDialog iconListDlg(this);
	if(iconListDlg.DoModal() == IDOK)
	{
		CString iconPath;
		if(iconListDlg.GetSelectedIconPath(iconPath))
		{
			HBITMAP hBmp = CXTPImageManagerIcon::LoadBitmapFromFile(iconPath);
			DeleteObject(m_macroIcon.SetBitmap(hBmp));
			pMacro->SetIconPath(iconPath);
			GetIEditor()->GetToolBoxManager()->UpdateMacroIcon(macroIndex);
		}
	}
}

//////////////////////////////////////////////////////////////////////////
void CToolsConfigPage::OnClearMacroIcon()
{
	int macroIndex = m_macroList.GetCurSel();
	if( macroIndex == LB_ERR )
		return;

	CToolBoxMacro* pMacro = (CToolBoxMacro*)m_macroList.GetItemData(macroIndex);
	DeleteObject(m_macroIcon.SetBitmap(NULL));
	pMacro->SetIconPath("");
	GetIEditor()->GetToolBoxManager()->UpdateMacroIcon(macroIndex);
}